/******************************************************************************/
/*                                                                            */
/*                       Copyright (c) HANBACK ELECTRONICS                    */
/*                              All rights reserved.                          */
/*                                                                            */
/*                             http://www.hanback.com                         */
/*                                                                            */
/******************************************************************************/

/******************************************************************************/
/*                                                                            */
/*============================================================================*/
/* Permission to use, copy, modify, and distribute this software and its      */
/* documentation are reserved by above authors and Hanback electronics.       */
/* The above copyright notice and authors must be described in this software. */
/*============================================================================*/
/*                                                                            */
/******************************************************************************/
#include "Opt_App.h"

module Opt_NO_AppM {

  uses {
    interface Boot;
    interface Leds;
    interface Timer<TMilli>;

    interface Interaction;
    interface StdControl as SCSuartDBGstd;
    interface SCSuartDBG;

    interface SplitControl as RadioControl;
    interface AMSend;
    interface Receive;
  }

} implementation {

  #define MyOPT_Type OPT_NO

  norace message_t TXData;
  norace App_struct_t AP_Frame;
  norace uint8_t MsgBuff[64], myAppType, myOptType, StreamingDataFlag=0, Current_App_size, reading;
  norace oscilloscope_t local;

  //void SensorsPrint (uint8_t App_size);

  //////////////////////////////////////////////////////////
  task void TryToConfigure() {call Interaction.StartConfiguration (&AP_Frame);}
  task void TryToSetTimer()  {call Interaction.SetSamplingTime(local.interval);}
  //////////////////////////////////////////////////////////

  event void Boot.booted() {
    call SCSuartDBGstd.start();
    call RadioControl.start();
  }

  event void RadioControl.startDone(error_t error) {
    if(error==SUCCESS){
        // inital delay.
	call Timer.startOneShot(2000);
    }else{
	call RadioControl.start();
    }
  }

  event void RadioControl.stopDone(error_t error) {}

  //////////////////////////////////////////////////////////

  event void Interaction.StartDoneConfiguration(uint8_t appType, uint8_t optType) {

    //sprintf(MsgBuff, "%d myAppType:%X, myOptType:%X\r\n", 1, appType, optType);
    //call SCSuartDBG.UARTSend(MsgBuff, strlen(MsgBuff));
 
    if (optType != MyOPT_Type) {
	post TryToConfigure();
	return;
    }
    
    call Leds.led0On();

    myAppType = appType;
    myOptType = optType;

    local.interval = DEFAULT_INTERVAL;
    local.id = 1;
    local.count = reading = 0;
    
    post TryToSetTimer();
  }
  
  //////////////////////////////////////////////////////////

  event void Timer.fired(){
    post TryToConfigure();
    return;
  }

  //////////////////////////////////////////////////////////

  event void Interaction.getSensorDataDone(App_struct_t *App_Payload, uint8_t App_size){
    call Leds.led1Toggle();
    
    // AP_Frame.sensor.Sdata.ADC_data[0] means the sensor value
    sprintf(MsgBuff, "%d recv Data:%u \r\n", 1, AP_Frame.AppData.sensor.Sdata.ADC_data[0]);
    call SCSuartDBG.UARTSend(MsgBuff, strlen(MsgBuff));


    local.readings[reading++] = AP_Frame.AppData.sensor.Sdata.ADC_data[0]; //sensor value

    if (reading == NREADINGS) {
	memcpy(call AMSend.getPayload(&TXData, sizeof(&TXData)), &local, sizeof(oscilloscope_t));
	if (call AMSend.send(AM_BROADCAST_ADDR, &TXData, sizeof(oscilloscope_t)) == SUCCESS){
		call Leds.led2On();
	}
	reading = 0;
	local.count++;
    }
  }

  event void Interaction.Urgency_Data (uint8_t *Urgency_Payload, uint8_t len) {

  }

  //////////////////////////////////////////////////////////

  event void AMSend.sendDone(message_t* msg, error_t error) {
    call Leds.led2Off();
  }

  event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len) {
    oscilloscope_t *omsg = payload;
    if (omsg->version > local.version){
	local.version = omsg->version;
	local.interval = omsg->interval;
	post TryToSetTimer();
    }

    if (omsg->count > local.count){
	local.count = omsg->count;
    }
    return msg;
  }

}
